"""
author: liuxu
date: 2025/5/30
description: 测试hipgdb基本功能
"""
import os
import allure
import pytest

from common.logger_ctrl import mylogger
from common.ssh_command import exec_cmd, InteractiveExecutor
from base_public.testbase import BasePublic
from setting import CPP_DIR


@pytest.mark.high
@allure.feature('hipgdb基本功能')
class TestHipgdb(BasePublic):
    def _get_debug_testcase(self):
        # 编译用例
        des_exe_name = self.compile_source_code(src_file_name=f"gdb_case/matrix_err.cpp", des_exe_name="matrix_err-g",
                                                compile_paras="-g -O0")
        return des_exe_name

    def test_hipgdb_basic_info(self, test_env):
        """
        测试查看hipgdb版本等信息
        :param test_env:
        :return:
        """
        test_cmds = """hipgdb --version
        hipgdb --help
        hipgdb --configuration"""
        for cmd in test_cmds.splitlines():
            ret, output = exec_cmd(cmd.strip(), cwd=test_env)
            assert ret is True

    @pytest.mark.high
    def test_hipgdb_breakpoint(self, test_env):  # 4.0驱动不支持核函数断点功能
        """
        测试hipgdb的断点功能
        :return:
        """
        break_prompt = "Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]"
        # -q, --quiet, --silent: Do not print version number on startup
        with InteractiveExecutor(command=f"hipgdb -q {self._get_debug_testcase()}", prompt="(gdb) ") as gdb_obj:
            gdb_obj.execute("run")  # 临时规避Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal]问题
            out, err = gdb_obj.execute("break matrixTranspose", prompt=[break_prompt, "(gsb)"])  # 添加函数名断点
            if "Make breakpoint pending on future shared library load? (y or [n])" in out:
                out, err = gdb_obj.execute("y")
                assert err == ""
            out, err = gdb_obj.execute("break 50 if x==1048576")  # 添加行号和条件断点
            out, err = gdb_obj.execute("info breakpoints")  # 查看断点信息
            out, err = gdb_obj.execute("disable 2")  # 停用断点
            out, err = gdb_obj.execute("enable")  # 启用断点
            out, err = gdb_obj.execute("delete 2")  # 删除断点
            out, err = gdb_obj.execute("run")  # 运行程序
            out, err = gdb_obj.execute("print x")
            out, err = gdb_obj.execute("step")
            out, err = gdb_obj.execute("next")
            out, err = gdb_obj.execute("continue")
            out, err = gdb_obj.execute("quit")


    def test_hipgdb_show_info(self, test_env, dcu_info):
        """
        测试hipgdb查看环境信息
        :return:
        """
        with InteractiveExecutor(command=f"hipgdb -q {self._get_debug_testcase()}", prompt="(gdb) ") as gdb_obj:
            out, err = gdb_obj.execute("info queues")  # 打印队列信息
            assert err == ""

            out, err = gdb_obj.execute("info lanes") # 查看 lanes 信息
            # assert err == ""

            out, err = gdb_obj.execute("info registers")  # 查看寄存器信息
            # assert err == ""

            out, err = gdb_obj.execute("macro list")  # 列出所有使用指令「macro define」定义的宏定义。
            # assert err == ""

            out, err = gdb_obj.execute("show architecture")  # 打印目标文件架构信息
            # assert dcu_info["architecture"] in out and err == ""

            out, err = gdb_obj.execute("show environment")  # 打印当前的环境变量
            assert "LD_LIBRARY_PATH=" in out and err == ""

            out, err = gdb_obj.execute("disassemble")  # 打印汇编指令信息
            # assert err == ""


    def test_hipgdb_frame(self, test_env):
        """
        查看堆栈信息
        :param test_env:
        :return:
        """
        with InteractiveExecutor(command=f"hipgdb -q {self._get_debug_testcase()}", prompt="(gdb) ") as gdb_obj:
            out, err = gdb_obj.execute("run")
            assert "Starting program: " in out
            assert err=="" or "amd-dbgapi: warning: AMD GPU driver's version 1.3 not supported (version 1.x where x >= 5 required)" in err

            out, err = gdb_obj.execute("backtrace")  # bt，查看堆栈
            assert len(out.splitlines()) > 2
            assert err == ""






